import {
    LS_NAME,
    TAB_KEY_QI_TA,
    PUNCTUATION_REG,
} from "../../configs/index.js";
import {
    getLS,
} from "../../utils/common.js";

Page({
    data: {
        tabKey: '',
        uploadTime: '',
        isQITA: false,
        articleItem: {},
        isUserInputEmpty: true,
        isShowMissing: true,
        textLineList: [],
        isFinish: false,
        finishPercent: 0,
        audioCurrentTime: 0,
        audioDuration: 0,
        isPlayingAudio: false,
    },
    onLoad: function (option) {
        const {
            activeTabKey: tabKey,
            uploadTime,
        } = option;
        const isQITA = tabKey === TAB_KEY_QI_TA;
        const englishColze = getLS();
        const activeArticles = englishColze[tabKey] || {};
        const articleItem = activeArticles[uploadTime] || {};
        this.setData({
            tabKey,
            uploadTime,
            isQITA,
            articleItem,
        });
        wx.setNavigationBarTitle({
            title: articleItem.fileTitle,
        });
        this.loadArticle();
        this.initAudio({
            title: articleItem.fileSubTitleZh,
            src: articleItem.audioUrl,
        });
    },
    onUnload: function () {
        this.audioStop();
    },
    loadArticle: function () {
        const {
            tabKey,
            uploadTime
        } = this.data;
        const englishColze = getLS();
        const activeArticles = englishColze[tabKey] || {};
        const articleItem = activeArticles[uploadTime];
        let {
            fileTitle,
            fileText,
            audioUrl,
            totalTime,
            jumpTimes,
        } = articleItem;
        if (String(fileText).trim() === "") {
            return;
        }
        let sourceTxtArr = fileText.split(/\n/);
        let textLineList = [];
        let notEmptyLineCount = 0;
        for (let m = 0; m < sourceTxtArr.length; m++) {
            let textLineSplitList = [];
            let textLine = sourceTxtArr[m].trim();
            if (textLine === '') {
                continue;
            }
            let allPuns = textLine.match(PUNCTUATION_REG);
            let pIndexStart = 0;
            let punIndex = 0;
            let isFillBefore = true;
            if (allPuns && allPuns.length > 0) {
                allPuns.forEach((pun, n) => {
                    punIndex = textLine.indexOf(pun, pIndexStart);
                    let wordBeforePun = textLine.substring(
                        pIndexStart,
                        punIndex
                    );
                    let isFill =
                        isFillBefore || !/^[a-zA-Z]{2,}$/.test(wordBeforePun) ?
                        false :
                        Math.random() >= 0.5;
                    pIndexStart = punIndex + pun.length;
                    isFillBefore = isFill;
                    textLineSplitList.push({
                        indexA: notEmptyLineCount,
                        indexB: n,
                        wordBeforePun,
                        pun,
                        isFill,
                        width: this.getInputWidth(wordBeforePun),
                        // userInput: m < sourceTxtArr.length - 2 ? wordBeforePun : "",
                    });
                });
            }
            if (punIndex + 1 < textLine.length) {
                let wordBeforePun = textLine.substring(pIndexStart);
                textLineSplitList.push({
                    wordBeforePun,
                    pun: "",
                    isFill: false,
                });
            }
            let textLineItem = {
                textLine,
                textLineSplitList,
            };
            if (jumpTimes && jumpTimes.length > notEmptyLineCount) {
                let startTimeStr = jumpTimes[notEmptyLineCount];
                let startTime = this.changeTimeStr2Num(startTimeStr);
                let nextStartTimeStr = jumpTimes.length > notEmptyLineCount + 1 ? jumpTimes[notEmptyLineCount + 1] : totalTime;
                let endTime = this.changeTimeStr2Num(nextStartTimeStr);
                Object.assign(textLineItem, {
                    startTime,
                    endTime,
                });
            }
            textLineList.push(textLineItem);
            notEmptyLineCount++;
        }
        this.setData({
            articleItem,
            textLineList,
            isFinish: false,
            finishPercent: 0,
        });
        wx.setNavigationBarTitle({
            title: articleItem.fileTitle,
        });
    },
    changeTimeStr2Num: function (timeStr) {
        let time = 0;
        if (!timeStr) {
            return time;
        }
        const tempA = timeStr.split('.');
        let hhmmssStr = tempA.length > 0 ? tempA[0] : '';
        let miStr = tempA.length > 1 ? tempA[1] : '';
        let tempB = hhmmssStr.split(':');
        tempB.reverse();
        let ssStr = tempB.length > 0 ? tempB[0] : '';
        let mmStr = tempB.length > 1 ? tempB[1] : '';
        let hhStr = tempB.length > 2 ? tempB[2] : '';
        let hh = Number(hhStr);
        let mm = Number(mmStr);
        let ss = Number(ssStr);
        let mi = Number(miStr);
        time = hh * 60 * 60 * 1000 + mm * 60 * 1000 + ss * 1000 + mi;
        return time;
    },
    clearUserInput: function () {
        const {
            articleItem,
            isUserInputEmpty,
            textLineList,
        } = this.data;
        if (isUserInputEmpty) {
            return;
        }
        (textLineList || []).forEach((sourceTextLine) => {
            const {
                textLineSplitList
            } = sourceTextLine;
            (textLineSplitList || []).forEach((textLineSplit) => {
                Object.assign(textLineSplit, {
                    userInput: "",
                });
            });
        });
        this.setData({
            textLineList,
            finishPercent: 0,
        });
        wx.setNavigationBarTitle({
            title: articleItem.fileTitle,
        });
    },
    updateFinishPercent: function () {
        const {
            textLineList,
            isFinish,
            articleItem,
        } = this.data;
        let allFillSum = 0;
        let okFillSum = 0;
        let isUserInputEmpty = true;
        (textLineList || []).forEach((sourceTextLine) => {
            const {
                textLineSplitList
            } = sourceTextLine;
            (textLineSplitList || []).forEach((textLineSplit) => {
                const {
                    wordBeforePun,
                    pun,
                    isFill,
                    userInput = "",
                } = textLineSplit;
                if (!isFill) {
                    return;
                }
                allFillSum += 1;
                const inputVal = String(userInput).trim();
                const isEmpty = inputVal === "";
                const isEqual = inputVal === wordBeforePun;
                if (isEqual) {
                    okFillSum += 1;
                }
                if (!isEmpty) {
                    isUserInputEmpty = false;
                }
            });
        });
        const finishPercent =
            allFillSum > 0 ?
            parseFloat((okFillSum / allFillSum) * 100).toFixed(0) :
            0;
        const stateNew = {
            textLineList,
            finishPercent,
            isUserInputEmpty,
        };
        if (!isFinish && finishPercent >= 100) {
            Object.assign(stateNew, {
                isFinish: true,
            });
            this.updateArticle({
                isAddFinishCount: true,
            });
        }
        this.setData(stateNew);
        let title = articleItem.fileTitle;
        if (finishPercent > 0) {
            title = `${finishPercent}% ${title}`
        }
        wx.setNavigationBarTitle({
            title,
        });
    },
    updateArticle: function ({
        isAddFinishCount = false
    }) {
        const {
            tabKey,
            uploadTime
        } = this.data;
        const englishColze = getLS();
        const activeArticles = englishColze[tabKey] || {};
        const articleItem = activeArticles[uploadTime];
        let {
            fileTitle,
            fileText,
            audioUrl,
            finishCount = 0
        } = articleItem;
        if (isAddFinishCount) {
            const finishCountNew = finishCount + 1;
            const modifyTime = new Date().getTime();
            Object.assign(articleItem, {
                finishCount: finishCountNew,
                modifyTime,
            });
            const eventChannel = this.getOpenerEventChannel()
            eventChannel.emit('updateItem', {
                uploadTime,
                finishCount: finishCountNew,
                modifyTime,
            });
        }
        wx.setStorageSync(LS_NAME, englishColze);
    },
    inputChange: function (event) {
        const {
            indexa: indexA,
            indexb: indexB,
        } = event.currentTarget.dataset;
        const {
            value,
        } = event.detail;
        const textLineSplit = this.data.textLineList[indexA].textLineSplitList[indexB];
        Object.assign(
            textLineSplit, {
                userInput: value,
            }
        );
        if (value === '' || value === textLineSplit.wordBeforePun) {
            Object.assign(textLineSplit, {
                isShowCorrectWord: false,
            });
        }
        this.updateFinishPercent();
    },
    toggleMissing: function () {
        this.setData({
            isShowMissing: !this.data.isShowMissing,
        });
    },
    getRpx: function () {
        const winWidth = wx.getSystemInfoSync().windowWidth;
        return 750 / winWidth;
    },
    getInputWidth: function (text) {
        //iPhone5
        const LETTER_WIDTH_PX = {
            'a': 8.953125,
            'b': 9.390625,
            'c': 8.765625,
            'd': 9.390625,
            'e': 8.890625,
            'f': 5.96875,
            'g': 9.46875,
            'h': 8.90625,
            'i': 4.109375,
            'j': 4.28125,
            'k': 8.46875,
            'l': 3.765625,
            'm': 13.6875,
            'n': 8.953125,
            'o': 9.390625,
            'p': 9.390625,
            'q': 9.390625,
            'r': 5.84375,
            's': 8.09375,
            't': 5.6875,
            'u': 8.96875,
            'v': 7.71875,
            'w': 12.09375,
            'x': 8.15625,
            'y': 7.9375,
            'z': 7.796875,
            'A': 10.515625,
            'B': 10.84375,
            'C': 11.65625,
            'D': 11.296875,
            'E': 10.203125,
            'F': 9.234375,
            'G': 11.96875,
            'H': 11.53125,
            'I': 3.796875,
            'J': 8.28125,
            'K': 11.046875,
            'L': 9.421875,
            'M': 14.125,
            'N': 11.515625,
            'O': 12.28125,
            'P': 10.28125,
            'Q': 12.28125,
            'R': 10.828125,
            'S': 10.125,
            'T': 9.90625,
            'U': 11.4375,
            'V': 10.234375,
            'W': 14.890625,
            'X': 10.203125,
            'Y': 10.59375,
            'Z': 9.984375,
        };
        let widthSum = 16;
        for (let ind in text) {
            widthSum += LETTER_WIDTH_PX[text[ind]] * 2.34375;
        }
        return widthSum;
    },
    toggleCorrectWord: function (event, isShow = true) {
        const {
            indexa: indexA,
            indexb: indexB,
        } = event.currentTarget.dataset;
        const {
            textLineList
        } = this.data;
        const textLineSplit = textLineList[indexA].textLineSplitList[indexB];
        Object.assign(
            textLineSplit, {
                isShowCorrectWord: isShow,
            }
        );
        this.setData({
            textLineList,
        });
    },
    showCorrectWord: function (event) {
        this.toggleCorrectWord(event, true);
    },
    hideCorrectWord: function (event) {
        this.toggleCorrectWord(event, false);
    },
    initAudio: function ({
        title = '',
        src = '',
        playbackRate = 1,
    } = {}) {
        Object.assign(getApp().audioCtx, {
            title,
            src,
            loop: true,
            obeyMuteSwitch: false,
            playbackRate,
            volume: 1,
        });
        this.setData({
            audioTitle: title,
        });
    },
    audioPlay: function () {
        getApp().audioCtx.play();
        this.setData({
            isPlayingAudio: true,
        });
        this.updateProgress();
    },
    audioPause: function () {
        getApp().audioCtx.pause();
        this.setData({
            isPlayingAudio: false,
        });
        clearTimeout(this.audioTimer);
    },
    audioStop: function () {
        getApp().audioCtx.stop();
        this.setData({
            audioCurrentTime: 0,
            isPlayingAudio: false,
        });
        clearTimeout(this.audioTimer);
    },
    jumpToTime: function (event) {
        const {
            starttime: audioCurrentTime,
        } = event.currentTarget.dataset;
        getApp().audioCtx.seek(audioCurrentTime / 1000);
        if (getApp().audioCtx.paused) {
            getApp().audioCtx.play();
        }
        this.setData({
            isPlayingAudio: true,
            audioCurrentTime,
        });
        clearTimeout(this.audioTimer);
        this.updateProgress();
    },
    updateProgress: function () {
        this.audioTimer = setTimeout(() => {
            let audioDuration = getApp().audioCtx.duration.toFixed(3) * 1000;
            let audioCurrentTime = getApp().audioCtx.currentTime.toFixed(3) * 1000;
            this.setData({
                audioCurrentTime: audioCurrentTime >= audioDuration ? 0 : audioCurrentTime,
                audioDuration,
            })
            audioCurrentTime <= 500 && console.log('==audioDuration', this.getHHMMSSMI(audioDuration), 'audioCurrentTime', audioCurrentTime);
            if (audioCurrentTime > 0 && audioCurrentTime >= audioDuration) {
                clearTimeout(this.audioTimer);
            }
            this.updateProgress();
        }, 250);
    },
    sliderChange: function (e) {
        const audioCurrentTime = e.detail.value;
        this.setData({
            audioCurrentTime,
        })
        this.audioSeek(audioCurrentTime);
    },
    audioSeek: function (audioCurrentTime) {
        getApp().audioCtx.seek(audioCurrentTime / 1000);
        this.updateProgress();
    },
    getHHMMSSMI: function (time) {
        let hh = parseInt(time / (60 * 60 * 1000));
        let mm = parseInt(time / (60 * 1000) - hh * 60);
        let ss = parseInt(time / 1000 - hh * 60 * 60 - mm * 60);
        let mi = time - hh * 60 * 60 * 1000 - mm * 60 * 1000 - ss * 1000;
        let mm2 = mm <= 9 ? `0${mm}` : mm;
        let ss2 = ss <= 9 ? `0${ss}` : ss;
        let mi3 = mi <= 9 ? `00${mi}` : mi <= 99 ? `0${mi}` : mi;
        if (hh > 0) {
            return `${hh}:${mm2}:${ss2}.${mi3}`;
        }
        return `${mm}:${ss2}.${mi3}`;
    },
})
